import {
    useEffect,
    useMemo,
    useState,
} from 'react';
import {createPortal} from 'react-dom';
import {getComponentById, useComponentsStore} from '../../stores/components';
import {Dropdown, Space} from 'antd';
import {DeleteOutlined} from '@ant-design/icons';
import {throttleHandle} from "../../utils/throttle.ts";

interface SelectedMaskProps {
    portalWrapperClassName: any
    containerClassName: string
    componentId: number;
}

function SelectedMask({containerClassName, portalWrapperClassName, componentId}: SelectedMaskProps) {
    const [position, setPosition] = useState({
        left: 0,
        top: 0,
        width: 0,
        height: 0,
        labelTop: 0,
        labelLeft: 0,
    });

    const {
        components,
        currentComponentId,
        deleteComponent,
        setCurrentComponent,
        currentComponent,
        moveComponent
    } = useComponentsStore();
    const findPage = (handle?: any) => {
        // 查找自定义属性值
        const el = document.querySelector(`[data-component-id="1"]`);
        if (!el) return;
        if (!handle) return el
        el.addEventListener('scroll', handle)
        return el
    }

    // 当前选中组件变化时
    useEffect(() => {
        const Handle = () => {
            throttleHandle(() => {
                updatePosition();
            }, 100)
        }
        // 创建一个ResizeObserver实例，观察被选中元素的尺寸变化
        const observer = new ResizeObserver(() => {
            Handle();
        });

        const el = findPage()
        if (!el) return
        observer.observe(el)
        return () => {
            // 移除observer，停止监听
            observer.unobserve(el!)
            observer.disconnect()
        }
    }, [componentId, currentComponent?.parentId]);

    // 监听组件变化
    useEffect(() => {
        setTimeout(() => {
            updatePosition();
        }, 500)

    }, [components]);

    // 监听窗口变化
    useEffect(() => {
        const resizeHandler = () => {
            throttleHandle(() => {
                updatePosition();
            }, 100)
        }
        window.addEventListener('resize', resizeHandler)
        return () => {
            window.removeEventListener('resize', resizeHandler)
        }
    }, [updatePosition]);

    // 监听滚动事件
    useEffect(() => {
        const scrollHandle = () => {
            throttleHandle(() => {
                updatePosition();
            }, 100)
        }
        const el = findPage(scrollHandle)
        if (!el) return;
        el?.addEventListener('scroll', scrollHandle)
        return () => {
            el?.removeEventListener('scroll', scrollHandle)
        }
    }, [updatePosition]);


    function updatePosition() {
        if (!componentId) return;
        const container = document.querySelector(`.${containerClassName}`);
        if (!container) return;

        const node = document.querySelector(`[data-component-id="${currentComponentId!}"]`);
        if (!node) return;
        const {top, left, width, height} = node.getBoundingClientRect();
        const {top: containerTop, left: containerLeft} = container.getBoundingClientRect();

        let labelTop = top - containerTop + container.scrollTop;
        let labelLeft = left - containerLeft + width;

        if (labelTop <= 0) {
            labelTop -= -20;
        }

        setPosition({
            top: top - containerTop + container.scrollTop,
            left: left - containerLeft + container.scrollTop,
            width,
            height,
            labelTop,
            labelLeft,
        });
    }

    const curComponent = useMemo(() => {
        return getComponentById(componentId, components);
    }, [componentId]);

    // 删除当前选中的组件
    function handleDelete() {
        deleteComponent(componentId!);
        setCurrentComponent(null!);
    }

    // 获取当前选中的组件
    const curSelectedComponent = useMemo(() => {
        return getComponentById(componentId, components);
    }, [componentId]);

    // 获取当前组件的所有父组件
    const parentComponents = useMemo(() => {
        const parentComponents = [];
        let component = curComponent;

        while (component?.parentId) {
            component = getComponentById(component.parentId, components)!;
            parentComponents.push(component);
        }

        return parentComponents;

    }, [curComponent]);

    const removeComponent = (position: string) => {
        if (!currentComponentId || !currentComponent?.parentId) return;
        moveComponent(currentComponentId, currentComponent?.parentId, position)
    }

    return portalWrapperClassName.current && createPortal((
        <>
            <div
                style={{
                    position: "absolute",
                    left: position.left,
                    top: position.top,
                    backgroundColor: "rgba(0, 0, 255, 0.1)",
                    border: "1px dashed blue",
                    pointerEvents: "none",
                    width: position.width,
                    height: position.height,
                    zIndex: 1,
                    borderRadius: 4,
                    boxSizing: 'border-box',
                    transition: 'all 0.1s ease',
                }}
            />
            <div
                style={{
                    position: "absolute",
                    left: position.labelLeft,
                    top: position.labelTop,
                    fontSize: "14px",
                    zIndex: 13,
                    display: (!position.width || position.width < 10) ? "none" : "inline",
                    transform: 'translate(-100%, -100%)',
                    transition: 'all 0.1s ease',
                }}
            >
                <Space>
                    <Dropdown
                        menu={{
                            items: parentComponents.map(item => ({
                                key: item.id,
                                label: item.desc,
                            })),
                            onClick: ({key}) => {
                                setCurrentComponent(+key)
                            }
                        }}
                        disabled={parentComponents.length === 0}
                    >
                        <div
                            style={{
                                padding: '0 8px',
                                backgroundColor: 'blue',
                                borderRadius: 4,
                                color: '#fff',
                                cursor: "pointer",
                                whiteSpace: 'nowrap',
                            }}
                        >
                            {curSelectedComponent?.desc}
                        </div>
                    </Dropdown>
                    <div className={'flex flex-1 w-[50px] justify-center'}>
                        <span className={'cursor-pointer mr-2'} onClick={() => removeComponent('up')}>⬆</span>
                        <span className={'cursor-pointer'} onClick={() => removeComponent('down')}>⬇</span>
                    </div>
                    {currentComponentId !== 1 && (
                        <div style={{padding: '0 8px', backgroundColor: 'blue'}}>
                            <DeleteOutlined onClick={handleDelete} style={{color: '#fff'}} />
                        </div>
                    )}
                </Space>
            </div>
        </>
    ), portalWrapperClassName.current)
}

export default SelectedMask;
